package com.yh.csx.crm.service;


import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.yh.csx.crm.core.enums.ApprovalTypeEnum;
import com.yh.csx.crm.core.enums.CooperationModeEnum;
import com.yh.csx.crm.core.enums.CustomerStatusEnum;
import com.yh.csx.crm.core.enums.UploadFileTypeEnum;
import com.yh.csx.crm.core.exception.BusinessException;
import com.yh.csx.crm.core.util.BeanUtils;
import com.yh.csx.crm.core.util.DateUtils;
import com.yh.csx.crm.dao.ApprovalMapper;
import com.yh.csx.crm.dao.CustomerCompanyExtMapper;
import com.yh.csx.crm.dao.CustomerMapper;
import com.yh.csx.crm.dao.CustomerSnapshotMapper;
import com.yh.csx.crm.dao.SysCreditLevelResultMapper;
import com.yh.csx.crm.dao.SysCustomerCategoryMapper;
import com.yh.csx.crm.dao.SysSalesPermissionMapper;
import com.yh.csx.crm.po.Customer;
import com.yh.csx.crm.po.CustomerCompanyExt;
import com.yh.csx.crm.po.SysCreditLevelResult;
import com.yh.csx.crm.po.SysCustomerCategory;
import com.yh.csx.crm.po.SysSalesPermission;
import com.yh.csx.crm.qo.CustomerListQo;
import com.yh.csx.crm.qo.CustomerQo;
import com.yh.csx.crm.service.logic.SapLogic;
import com.yh.csx.crm.service.request.ChangeCustomerReq;
import com.yh.csx.crm.service.request.CustomerAddReq;
import com.yh.csx.crm.service.request.CustomerListReq;
import com.yh.csx.crm.service.request.StartCreditApprovalReq;
import com.yh.csx.crm.service.request.StartTempCreditApprovalReq;
import com.yh.csx.crm.service.request.UploadFile;
import com.yh.csx.crm.service.request.UploadFilePO;
import com.yh.csx.crm.service.response.CompanyCodeInfoResp;
import com.yh.csx.crm.service.response.CustomerDetailsResp;
import com.yh.csx.crm.service.response.CustomerListResp;
import com.yh.csx.crm.service.vo.PageWrap;
import com.yh.csx.crm.service.vo.User;
import com.yh.csx.crm.vo.CustomerDetailVo;
import com.yh.csx.crm.vo.CustomerInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * CustomerService class
 *
 * @author huyalin
 * @date 2019/2/13
 */
@Slf4j
@Service
public class CustomerService {

    @Autowired
    CustomerMapper customerMapper;

    @Autowired
    ApprovalService approvalService;

    @Autowired
    SapLogic sapLogic;

    @Autowired
    SaleService saleService;

    @Autowired
    SysCustomerCategoryMapper sysCustomerCategoryMapper;

    @Autowired
    SysSalesPermissionMapper sysSalesPermissionMapper;

    @Autowired
    CustomerSnapshotMapper customerSnapshotMapper;

    @Autowired
    CustomerCompanyExtMapper customerCompanyExtMapper;

    @Autowired
    CacheService cacheService;

    @Autowired
    ApprovalMapper approvalMapper;

    @Autowired
    GeoService geoService;

    @Autowired
    AppTempService appTempService;

    @Autowired
    SysCreditLevelResultMapper sysCreditLevelResultMapper;



    /**
     * 获取客户详细信息
     * @param id
     * @return
     */
    public Customer getCustomer(Long id) {
        return customerMapper.selectByPrimaryKey(id);
    }

    /**
     * 获取客户详情
     * @param customerId
     * @return
     */
    public CustomerDetailsResp getCustomerDetailsResp(Long customerId) {
        Customer customer = this.getCustomer(customerId);
        if (customer.getCooperationMode().equals(CooperationModeEnum.TEMP.getCode())
                && (customer.getCustomerStatus().equals(CustomerStatusEnum.PENDING.getCode())
                || customer.getCustomerStatus().equals(CustomerStatusEnum.REJECT.getCode()))) {
            customer.setCreditLimit(customer.getTempCreditLimit());
            customer.setTempCreditLimit(BigDecimal.ZERO);
        }
        //查询客户类型
        String customerType = this.getOldCustomerType(customer.getCustomerCategoryId());
        CustomerDetailsResp cusP =  BeanUtils.convert(CustomerDetailsResp.class, customer);
        List<UploadFile> contractFileList= new ArrayList<>();
        List<UploadFile> thirdPartyCreditFileList= new ArrayList<>();
        List<UploadFilePO> uploadFilePOList = JSON.parseArray(customer.getFilePath(), UploadFilePO.class);
        uploadFilePOList.forEach(uploadFilePO -> {
            if (uploadFilePO.getType() == null) {
                contractFileList.add(uploadFilePO);
            }
            else if (uploadFilePO.getType().equals(UploadFileTypeEnum.CONTRACT.toString())) {
                contractFileList.add(uploadFilePO);
            }
            else if (uploadFilePO.getType().equals(UploadFileTypeEnum.THIRD_PARTY_CREDIT.toString())) {
                thirdPartyCreditFileList.add(uploadFilePO);
            }
        });
        cusP.setContractFileList(contractFileList);
        cusP.setThirdPartyCreditFileList(thirdPartyCreditFileList);
        cusP.setType(customerType);
        SysCreditLevelResult sysCreditLevelResult = sysCreditLevelResultMapper.selectByCreditLevel(customer.getCustomerLevel());
        if (sysCreditLevelResult != null) {
            cusP.setLevelDesc(sysCreditLevelResult.getRiskExplain());
        }
        return cusP;
    }

    /**
     * 获取客户类型
     * @param customerCategoryId
     * @return
     */
    public String getOldCustomerType(Integer customerCategoryId) {
//        String parentString =null;
//        String sonString=null;
//        String s=null;
//        parentString = sysCustomerCategoryMapper.selecParentCustermType(id);
//        sonString = sysCustomerCategoryMapper.selecSonCustermType(id);
//        if (null!= parentString && null!= sonString){
//            s=parentString+"/"+sonString;
//            return s;
//        }else {
//            return null;
//        }
        SysCustomerCategory sysCustomerCategory = sysCustomerCategoryMapper.selectByPrimaryKey(customerCategoryId);
        if (Objects.nonNull(sysCustomerCategory)) {
            return sysCustomerCategory.getFullName();
        }
        return "";
    }

//    public String getNewCustomerType(Long id) {
//        String s=null;
//        String parent =null;
//        String son=null;
//        parent = sysCustomerCategoryMapper.selecNewParentCustermType(id);
//        son = sysCustomerCategoryMapper.selecNewSonCustermType(id);
//        if (null!=parent && null!=son){
//            s=parent+"/"+son;
//            return s;
//        }else {
//            return null;
//        }
//
//
//    }

    /**
     * 修改客户信息
     * @param customer
     */
    public void modify(Customer customer) {
        customerMapper.updateByPrimaryKey(customer);
    }

    /**
     * 启用/禁用
     * @param customerId
     * @param enable
     * @return
     */
    public void enable(User user, Long customerId, Boolean enable) {
        Customer customer = customerMapper.selectByPrimaryKey(customerId);
        customer.setActiveFlag(enable);
        customer.setUpdateBy(user.getUserName());
        customerMapper.updateByPrimaryKeySelective(customer);
    }

    /**
     * 转移
     * @param
     * @param
     */
    @Transactional(rollbackFor = Exception.class)
    public void changeCustomer(User user, ChangeCustomerReq req) {
        SysSalesPermission permission = saleService.findSalesPermission(req.getSalesUserId());
        if (permission == null && req.getSalesUserId() != 0) throw new BusinessException("销售员不存在");
        List<Long> customerIdList = req.getCustomerIdList();
        customerIdList.forEach(customerId -> {
            if (approvalService.isNotRepeatStart(customerId)) {
                Customer record = new Customer();
                record.setId(customerId);
                record.setSalesUserId(permission != null ? permission.getUserId() : req.getSalesUserId());
                record.setSalesUserName(permission != null ? permission.getUserName() : "");
                record.setUpdateBy(user.getUserName());
                customerMapper.updateByPrimaryKeySelective(record);
            } else {
                throw new BusinessException("客户有审批中的单据");
            }
        });
    }

    /**
     * 转移
     * @param
     * @param
     */
    @Transactional(rollbackFor = Exception.class)
    public void changeCustomer(User user, Long customerId, Long salesUserId) {
        ChangeCustomerReq req = new ChangeCustomerReq();
        req.setCustomerIdList(Arrays.asList(customerId));
        req.setSalesUserId(salesUserId);
        changeCustomer(user, req);
    }

    /**
     * 获取我的客户列表包含
     * @param userId
     * @return
     */
    public List<Customer> getCustomerList(Long userId) {
        CustomerListQo customerListQo = new CustomerListQo();
        List<Long> salesUserIds = saleService.getPermitUserIds(userId);
        customerListQo.setSubordinateUserIdList(salesUserIds);
        List<Customer> customerList = customerMapper.selectByExample(customerListQo);
        return customerList;
    }



    /**
     * 获取我的客户列表
     * @param req
     * @return
     */
    public PageWrap<List<CustomerListResp>> getCustomerList(User user, CustomerListReq req) {
        CustomerListQo qo = BeanUtils.convert(CustomerListQo.class, req);
        if (Objects.nonNull(req.getBeginDate()) && Objects.nonNull(req.getEndDate())) {
            qo.setBeginDateStr(DateUtils.formatDate(qo.getBeginDate()));
            qo.setEndDateStr(DateUtils.formatDate(qo.getEndDate()));
        }
        qo.setSubordinateUserIdList(saleService.getPermitUserIds(user.getUserId()));

        Page<Object> page = PageHelper.startPage(req.getPageNum(), req.getPageSize());
        List<Customer> customerList = customerMapper.selectByExample(qo);
        List<CustomerListResp> respList = new ArrayList<>();
        customerList.forEach(customer -> {
            CustomerListResp customerListResp = BeanUtils.convert(CustomerListResp.class, customer);
            if (Objects.nonNull(customer.getTempCreditLimit()) &&
                    customer.getTempCreditLimit().doubleValue() > 0 &&
                    DateUtils.belongCalendar(new Date(), customer.getTempBeginTime(), customer.getTempEndTime())) {
                customerListResp.setTotalCreditLimit(customer.getCreditLimit().add(customer.getTempCreditLimit()));
            } else {
                customerListResp.setTempCreditLimit(BigDecimal.ZERO);
                customerListResp.setTotalCreditLimit(customer.getCreditLimit());
            }
            respList.add(customerListResp);
        });
        PageWrap pageWrap = new PageWrap<>();
        pageWrap.setValue(page);
        pageWrap.setResult(respList);
        return pageWrap;
    }




    /**
     * 新增客户(保存草稿)
     * @param req
     */
    public Customer addCustomer(User user, CustomerAddReq req) {

        Customer customer = BeanUtils.convert(Customer.class, req);
        customer.setChannelSecondCode(req.getFirstCategoryCode());
        if (customer.getCooperationMode().equals(CooperationModeEnum.TEMP.getCode())) {
            appTempService.prTemp(req.getSalesProvince(),req.getCreditLimit(),req.getTempEndTime());
            customer.setTempCreditLimit(customer.getCreditLimit());
            customer.setCreditLimit(BigDecimal.ZERO);
            customer.setTempBeginTime(DateUtils.oneDayBeginTime(customer.getTempBeginTime()));
            customer.setTempEndTime(DateUtils.oneDayEndTime(customer.getTempEndTime()));
        }
        if (StringUtils.isNotBlank(req.getRegionProvinceName()) &&
                StringUtils.isNotBlank(req.getRegionCity()) &&
                StringUtils.isNotBlank(req.getRegionArea())) {
            double[] resolveAddress = null;
            try {
                resolveAddress = geoService.resolveAddress(req.getRegionProvinceName() +
                        req.getRegionCity() + req.getRegionArea() + req.getAddressDetails());
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
            if (resolveAddress != null) {
                customer.setLongitude(BigDecimal.valueOf(resolveAddress[0]));
                customer.setLatitude(BigDecimal.valueOf(resolveAddress[1]));
            }
        }
        List<UploadFilePO> uploadFilePOList = new ArrayList<>();
        if (Objects.nonNull(req.getContractFileList())) {
            try {
                List<UploadFilePO> filePOList = BeanUtils.convertList(UploadFilePO.class, req.getContractFileList());
                filePOList.forEach(uploadFilePO -> {
                    uploadFilePO.setType(UploadFileTypeEnum.CONTRACT.toString());
                });
                uploadFilePOList.addAll(filePOList);
            } catch (Exception e) {
                log.error("解析附件时出错", e);
            }
        }
        if (Objects.nonNull(req.getThirdPartyCreditFileList())) {
            try {
                List<UploadFilePO> filePOList = BeanUtils.convertList(UploadFilePO.class, req.getThirdPartyCreditFileList());
                filePOList.forEach(uploadFilePO -> {
                    uploadFilePO.setType(UploadFileTypeEnum.THIRD_PARTY_CREDIT.toString());
                });
                uploadFilePOList.addAll(filePOList);
            } catch (Exception e) {
                log.error("解析附件时出错", e);
            }
        }
        Customer beforCustomer = null;
        if (Objects.nonNull(req.getId()) && Objects.nonNull(beforCustomer = customerMapper.selectByPrimaryKey(req.getId()))) {
            if (customerMapper.selectCountByCustomerName(req.getCustomerName(), req.getId()) > 0) {
                throw new BusinessException("客户名称已存在");
            }
            org.springframework.beans.BeanUtils.copyProperties(req, beforCustomer);
            if (beforCustomer.getCooperationMode().equals(CooperationModeEnum.TEMP.getCode())) {
                beforCustomer.setTempCreditLimit(req.getCreditLimit());
                beforCustomer.setCreditLimit(BigDecimal.ZERO);
                beforCustomer.setTempBeginTime(DateUtils.oneDayBeginTime(beforCustomer.getTempBeginTime()));
                beforCustomer.setTempEndTime(DateUtils.oneDayEndTime(beforCustomer.getTempEndTime()));
            }
            beforCustomer.setFilePath(JSON.toJSONString(uploadFilePOList));
            beforCustomer.setUpdateBy(user.getUserName());
            if (log.isDebugEnabled()) {
                log.debug("编辑客户信息" + customer.toString());
            }
            customerMapper.updateByPrimaryKeySelective(beforCustomer);
            return beforCustomer;
        } else {
            if (customerMapper.selectCountByCustomerName(req.getCustomerName(), null) > 0) {
                throw new BusinessException("客户名称已存在");
            }
            this.initCustomer(user, customer);
            customer.setFilePath(JSON.toJSONString(uploadFilePOList));
            if (log.isDebugEnabled()) {
                log.debug("入库客户信息" + customer.toString());
            }
            customerMapper.insertSelective(customer);
            return customer;
        }
    }


    /**
     * 初始化客户默认值
     * @param user
     * @param customer
     */
    public void initCustomer(User user, Customer customer) {
        if (Objects.isNull(customer.getSalesUserId()) || customer.getSalesUserId() == 0) {
            customer.setSalesUserId(user.getUserId());
            customer.setSalesUserName(user.getUserName());
        }
        if (Objects.isNull(customer.getTempBeginTime()) || Objects.isNull(customer.getTempEndTime())) {
            customer.setTempBeginTime(DateUtils.maxDateTime());
            customer.setTempEndTime(DateUtils.maxDateTime());
        }
        customer.setCreateBy(user.getUserName());
        customer.setSaleOrganization(customer.getCompanyCode()+"");//默认公司代码
        customer.setCreditRange(customer.getCompanyCode()+"");//默认公司代码
        customer.setChannelFirstCode("20");
        customer.setDistributionChannel("20");//写死
        customer.setSaleRegion("610000");//写死
    }

    /**
     * 新增客户并发起审批参数校验
     * @param req
     */
    private void addCustomerAndStartApprovalCheck(CustomerAddReq req) {
        if (Objects.isNull(req)) {
            throw new BusinessException("参数为空");
        }
        if (StringUtils.isBlank(req.getCustomerName())) {
            throw new BusinessException("客户名称不能为空");
        }
        if (StringUtils.isBlank(req.getFirstCategoryCode()) || StringUtils.isBlank(req.getSecondCategoryCode())) {
            throw new BusinessException("客户分类不能为空");
        }
        if (StringUtils.isBlank(req.getArchiveCategory())) {
            throw new BusinessException("档案分类不能为空");
        }
        if (StringUtils.isBlank(req.getCooperationMode())) {
            throw new BusinessException("合作模式不能为空");
        }
        if (StringUtils.isBlank(req.getPhone())) {
            throw new BusinessException("联系电话不能为空");
        }
        if (StringUtils.isBlank(req.getContactPerson())) {
            throw new BusinessException("联系人姓名不能为空");
        }
        if (StringUtils.isBlank(req.getRegionProvince()) || StringUtils.isBlank(req.getRegionProvinceName())
                || StringUtils.isBlank(req.getRegionCity())) {
            throw new BusinessException("客户地址省市不能为空");
        }
        if (StringUtils.isBlank(req.getAddressDetails())) {
            throw new BusinessException("客户详细地址不能为空");
        }
        if (StringUtils.isBlank(req.getBankAccountNumber())) {
            throw new BusinessException("银行账户不能为空");
        }
        if (StringUtils.isBlank(req.getBankAccountName())) {
            throw new BusinessException("银行户主不能为空");
        }
        if (StringUtils.isBlank(req.getCompanyCode())) {
            throw new BusinessException("公司代码不能为空");
        }
        if (StringUtils.isBlank(req.getPaymentTerms())) {
            throw new BusinessException("付款条件不能为空");
        }
//        if (StringUtils.isBlank(req.getPayMode())) {
//            throw new BusinessException("支付方式不能为空");
//        }
        if (StringUtils.isBlank(req.getPaymentDays())) {
            throw new BusinessException("账期不能为空");
        }
        if (Objects.isNull(req.getWrittenAmount()) || req.getWrittenAmount().signum() < 0) {
            throw new BusinessException("签单金额不能为空或负数");
        }
        if (StringUtils.isBlank(req.getB2bShopCode()) || StringUtils.isBlank(req.getB2bShopName())) {
            throw new BusinessException("所属门店编码和名称不能为空");
        }
        if (Objects.isNull(req.getSalesUserId()) || StringUtils.isBlank(req.getSalesUserName())) {
            throw new BusinessException("业务对接人不能为空");
        }
        if (StringUtils.isBlank(req.getTaxesCategory())) {
            throw new BusinessException("祱分类不能为空");
        }
        if (StringUtils.isBlank(req.getSalesProvince())) {
            throw new BusinessException("所属省区不能为空");
        }
        if (StringUtils.isBlank(req.getCustomerLevel())) {
            throw new BusinessException("客户级别不能为空");
        }
        if (req.getCooperationMode().equals(CooperationModeEnum.TEMP.getCode())) {
            if (Objects.isNull(req.getTempBeginTime()) || Objects.isNull(req.getTempEndTime())) {
                throw new BusinessException("合作模式为短期的客户必须指定信控有效时间");
            }
        }
        if (Objects.isNull(req.getCreditLimit()) || req.getCreditLimit().signum() < 0) {
            throw new BusinessException("信控额度不能为空或负数");
        }
        if ("undefined".equals(req.getBankNumber()) || "null".equals(req.getBankNumber()) ){
            throw new BusinessException("银行联行号不正确");
        }
    }

    /**
     * 新增客户并发起审批
     * @param user
     * @param req
     */
    @Transactional(rollbackFor = Exception.class)
    public void addCustomerAndStartApproval(User user, CustomerAddReq req) {
        /*判断必填字段*/
        this.addCustomerAndStartApprovalCheck(req);

        Customer customer = this.addCustomer(user, req);
        customer.setCustomerStatus(CustomerStatusEnum.ONGOING.getCode());
        customerMapper.updateByPrimaryKeySelective(customer);

        //Customer beforeCustomer, Customer afterCustomer,
        /*发起审批*/
        approvalService.startApproval(user, ApprovalTypeEnum.NEW, customer, customer, null);
    }

    /**
     * 查询客户列表
     *
     * @param qo
     * @return
     */
    public List<CustomerInfoVo> findCustomerInfoList(CustomerQo qo) {
        qo.setNotCustomerStatusList(Arrays.asList(CustomerStatusEnum.DEV.getCode()));
        if (qo.getSalesUserId() != null) {
            qo.setSalesUserIds(saleService.getPermitUserIds(qo.getSalesUserId()));
            qo.setSalesUserId(null);
        }
        if (qo.getOrderField() == null) {
            qo.setOrderField(0);
            qo.setSortType(1);
        }
        if (qo.isPageable()) {
            PageHelper.startPage(qo.getPageNum(), qo.getPageSize(), qo.isCount());
        }
        return customerMapper.selectCustomerInfoList(qo);
    }

    /**
     * 发起临时额度审批
     * @param user
     * @param req
     */
    @Transactional(rollbackFor = Exception.class)
    public void startTempCreditApproval(User user, StartTempCreditApprovalReq req) {
        Customer beforeCustomer = customerMapper.selectByPrimaryKey(req.getCustomerId());
        if (Objects.isNull(beforeCustomer)) {
            throw new BusinessException("客户不存在");
        }
        if (!beforeCustomer.getCustomerStatus().equals(CustomerStatusEnum.PASS.getCode())) {
            throw new BusinessException("该客户还未通过审批，不能发起临时额度调整");
        }
        if (!approvalService.isNotRepeatStart(beforeCustomer.getId())) {
            throw new BusinessException("已经有审批中的单据，不能重复发起");
        }
        if (this.isValidTempCredit(beforeCustomer)) {
            throw new BusinessException("已有生效中的临时额度");
        }
        if (beforeCustomer.getTempCreditLimit().doubleValue() > 0 && beforeCustomer.getTempBeginTime().after(new Date())) {
            throw new BusinessException("已有待生效的临时额度");
        }

        Customer afterCustomer = BeanUtils.convert(Customer.class, beforeCustomer);
        afterCustomer.setTempBeginTime(DateUtils.oneDayBeginTime(req.getBeginDate()));
        afterCustomer.setTempEndTime(DateUtils.oneDayEndTime(req.getEndDate()));
        afterCustomer.setTempCreditLimit(req.getTempCredit().subtract(afterCustomer.getCreditLimit()));

        approvalService.startApproval(user, ApprovalTypeEnum.TEMP_CREDIT, beforeCustomer, afterCustomer, req.getReason());
    }

    /**
     * 判断当前时间临时额度是否有效
     * @param customer
     * @return
     */
    public boolean isValidTempCredit(Customer customer) {
        if (Objects.nonNull(customer.getTempCreditLimit()) &&
                customer.getTempCreditLimit().doubleValue() > 0 &&
                DateUtils.belongCalendar(new Date(), customer.getTempBeginTime(), customer.getTempEndTime())) {
            return true;
        }
        return false;
    }

    /**
     * 发起固定额度审批
     * @param user
     * @param req
     */
    @Transactional(rollbackFor = Exception.class)
    public void startCreditApproval(User user, StartCreditApprovalReq req) {
        Customer beforeCustomer = customerMapper.selectByPrimaryKey(req.getCustomerId());
        Customer afterCustomer = BeanUtils.convert(Customer.class, beforeCustomer);
        if (Objects.isNull(beforeCustomer)) {
            throw new BusinessException("客户不存在");
        }
        if (!beforeCustomer.getCustomerStatus().equals(CustomerStatusEnum.PASS.getCode())) {
            throw new BusinessException("该客户还未通过审批，不能发起额度调整");
        }
        if (Objects.nonNull(beforeCustomer.getTempCreditLimit()) && beforeCustomer.getTempCreditLimit().doubleValue() > 0 &&
                DateUtils.belongCalendar(new Date(), beforeCustomer.getTempBeginTime(), beforeCustomer.getTempEndTime())) {
            throw new BusinessException("该客户有生效中的临时额度，不能发起额度调整");
        }

        if (!approvalService.isNotRepeatStart(beforeCustomer.getId())) {
            throw new BusinessException("已经有审批中的单据，不能重复发起");
        }
        if (beforeCustomer.getCooperationMode().equals(CooperationModeEnum.TEMP.getCode())) {
            appTempService.prTemp(req.getSalesProvince(),req.getCreditLimit(), req.getTempEndTime());
            afterCustomer.setTempCreditLimit(req.getCreditLimit());
            afterCustomer.setTempBeginTime(DateUtils.oneDayBeginTime(req.getTempBeginTime()));
            afterCustomer.setTempEndTime(DateUtils.oneDayEndTime(req.getTempEndTime()));
            approvalService.startApproval(user, ApprovalTypeEnum.TEMP_CREDIT, beforeCustomer, afterCustomer, null);

        } else {

            CustomerCompanyExt customerCompanyExt = customerCompanyExtMapper.selectCompanyCodeInfo(req.getCustomerId(), req.getCompanyCode());
            if (customerCompanyExt != null) {
                beforeCustomer.setCompanyCode(customerCompanyExt.getCompanyCode());
                beforeCustomer.setCreditLimit(customerCompanyExt.getCreditLimit());
                beforeCustomer.setCustomerLevel(customerCompanyExt.getCustomerLevel());
                beforeCustomer.setSaleOrganization(customerCompanyExt.getSaleOrganization());
                beforeCustomer.setPaymentTerms(customerCompanyExt.getPaymentTerms());
                beforeCustomer.setPaymentDays(customerCompanyExt.getPaymentDays());
            }

            afterCustomer.setCompanyCode(req.getCompanyCode());
            afterCustomer.setCreditLimit(req.getCreditLimit());
            afterCustomer.setCustomerLevel(req.getCustomerLevel());
            afterCustomer.setPaymentTerms(req.getPaymentTerms());
            afterCustomer.setPaymentDays(req.getPaymentDays());
            afterCustomer.setSaleOrganization(req.getCompanyCode());

            if (afterCustomer.getCreditLimit().compareTo(beforeCustomer.getCreditLimit()) == 0) {
                throw new BusinessException("额度没有发生变更");
            }
            approvalService.startApproval(user, ApprovalTypeEnum.CREDIT, beforeCustomer, afterCustomer, null);
        }
    }

    /**
     * 发起客户资料修改审批
     * @param user
     * @param req
     */
    @Transactional(rollbackFor = Exception.class)
    public void startCustomerModifyApproval(User user, CustomerAddReq req) {
        /*判断必填字段*/
        this.addCustomerAndStartApprovalCheck(req);
        if (Objects.nonNull(req.getTempBeginTime()) && Objects.nonNull(req.getTempEndTime())) {
            req.setTempBeginTime(DateUtils.oneDayBeginTime(req.getTempBeginTime()));
            req.setTempEndTime(DateUtils.oneDayEndTime(req.getTempEndTime()));
        }
        Customer beforeCustomer = customerMapper.selectByPrimaryKey(req.getId());
        beforeCustomer.setCreateTime(null);
        beforeCustomer.setCreateBy(null);
        beforeCustomer.setUpdateTime(null);
        beforeCustomer.setUpdateBy(null);
        Customer afterCustomer = BeanUtils.convert(Customer.class, beforeCustomer);
        List<String> ignoreProperties = new ArrayList<>();
        Field[] declaredFields = req.getClass().getDeclaredFields();
        for (Field field: declaredFields) {
            field.setAccessible(true);
            try {
                Object o = field.get(req);
                if (o == null) {
                    ignoreProperties.add(field.getName());
                }
            } catch (IllegalAccessException e) {
                log.error(e.getMessage(), e);
                throw new BusinessException("系统异常");
            }
        }
        String[] strings = ignoreProperties.toArray(new String[ignoreProperties.size()]);
        org.springframework.beans.BeanUtils.copyProperties(req, afterCustomer, strings);
        List<UploadFilePO> uploadFilePOList = new ArrayList<>();
        if (Objects.nonNull(req.getContractFileList())) {
            try {
                List<UploadFilePO> filePOList = BeanUtils.convertList(UploadFilePO.class, req.getContractFileList());
                filePOList.forEach(uploadFilePO -> {
                    uploadFilePO.setType(UploadFileTypeEnum.CONTRACT.toString());
                });
                uploadFilePOList.addAll(filePOList);
            } catch (Exception e) {
                log.error("解析附件时出错", e);
            }
        }
        if (Objects.nonNull(req.getThirdPartyCreditFileList())) {
            try {
                List<UploadFilePO> filePOList = BeanUtils.convertList(UploadFilePO.class, req.getThirdPartyCreditFileList());
                filePOList.forEach(uploadFilePO -> {
                    uploadFilePO.setType(UploadFileTypeEnum.THIRD_PARTY_CREDIT.toString());
                });
                uploadFilePOList.addAll(filePOList);
            } catch (Exception e) {
                log.error("解析附件时出错", e);
            }
        }
        afterCustomer.setFilePath(JSON.toJSONString(uploadFilePOList));

        if (afterCustomer.equals(beforeCustomer)) {
            throw new BusinessException("没有任何变更");
        }
        if (null==afterCustomer.getFilePath()) {
            afterCustomer.setFilePath("[]");
        }

        /*新增或修改*/
        if (Objects.isNull(req.getId()) || Objects.isNull(customerMapper.selectByPrimaryKey(req.getId()))) {
            throw new BusinessException("客户不存在");
        }

        /*发起审批*/
        approvalService.startApproval(user, ApprovalTypeEnum.MODIFY, beforeCustomer, afterCustomer, null);
    }
    /**
     * 查询客户明细
     *
     * @param customerId
     * @return
     */
    public CustomerDetailVo findCustomerDetail(Long customerId) {
        CustomerDetailVo customerDetailVo = customerMapper.selectCustomerDetail(customerId);
        Customer customer = BeanUtils.convert(Customer.class, customerDetailVo);
        if (!this.isValidTempCredit(customer)) {
            customerDetailVo.setTempCreditLimit(BigDecimal.ZERO);
        }
        return customerDetailVo;
    }

    public List<String> getCustomerComp(String customerName){
        String cuComp = "";
        String csComp="";
        Customer customer = customerMapper.selectComp(customerName);

        cuComp=customer.getCompanyCode();
        csComp=  customerSnapshotMapper.selectComp(customerName);
        List<String> l=  customerCompanyExtMapper.selectCompList(customer.getId());

        List<String> list = new ArrayList<>();
        list.add(cuComp);
        if (null != csComp && !list.contains(csComp)){
            list.add(csComp);
        }
        for (String s : l){
            if (!list.contains(s)){
                list.add(s);
            }
        }
        return list;
    }

    public boolean selectCustomerIfNot(Long customerId ,String companyCode){

        Customer customer = customerMapper.selectByPrimaryKey(customerId);
        if (companyCode.equals(customer.getCompanyCode())){
            return false;
        }

        String companyC = customerCompanyExtMapper.selectComp(customerId);
        if (null != companyC && companyCode.equals(companyC)){
            return false;
        }

        return true;
    }

    public CompanyCodeInfoResp getCompanyCodeInfo(Long customerId, String companyCode){
       CustomerCompanyExt cu =  customerCompanyExtMapper.selectCompanyCodeInfo(customerId,companyCode);
        Customer customer = customerMapper.selectByPrimaryKey(customerId);
        CompanyCodeInfoResp companyCodeInfoResp = new CompanyCodeInfoResp();
        if (null != cu){
            companyCodeInfoResp.setCompanyCode(cu.getCompanyCode());
            companyCodeInfoResp.setSaleOrganization(cu.getSaleOrganization());
            companyCodeInfoResp.setPaymentTerms(cu.getPaymentTerms());
            companyCodeInfoResp.setCreditLimit(cu.getCreditLimit());
            companyCodeInfoResp.setPaymentDays(cu.getPaymentDays());
            companyCodeInfoResp.setCustomerLevel(cu.getCustomerLevel());
        }
        if (null != customer && companyCode.equals(customer.getCompanyCode())){
            companyCodeInfoResp.setPayMode(customer.getPayMode());
            companyCodeInfoResp.setPlanSalesAmount(customer.getPlanSalesAmount());
            companyCodeInfoResp.setWrittenAmount(customer.getWrittenAmount());
            companyCodeInfoResp.setCompanyCode(customer.getCompanyCode());
            companyCodeInfoResp.setSaleOrganization(customer.getSaleOrganization());
            companyCodeInfoResp.setPaymentTerms(customer.getPaymentTerms());
            companyCodeInfoResp.setCreditLimit(customer.getCreditLimit());
            companyCodeInfoResp.setPaymentDays(customer.getPaymentDays());
            companyCodeInfoResp.setCustomerLevel(customer.getCustomerLevel());
            if (null != customer.getCooperationMode() && customer.getCooperationMode().equals("02")){
                companyCodeInfoResp.setTempBeginTime(customer.getTempBeginTime());
                companyCodeInfoResp.setTempEndTime(customer.getTempEndTime());
            }
        }
        return companyCodeInfoResp;
    }
}
